package com.xiukelai.springboot.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 控制类的基类，所有Controller必须继承此类
 *
 * @author lixueju
 * @since 2019/3/12 17:43
 */
public class BaseController{

    /**
     * 登录用户储存的key前缀
     */
    private final String USER_TOKEN_PREFIX = "userToken:";


    @Autowired
    protected HttpServletRequest request;

    /**
     * 自定义对象中日期格式，成功通用返回方法。
     * 日期格式默认为yyyy-MM-dd HH:mm:ss
     *
     * @param obj        需要返回的数据对象
     * @param dateFormat 日期格式（例如：yyyy-MM-dd）
     * @return
     */
    protected String callbackWithDateFormat(Object obj, String dateFormat) {
        if (!(obj instanceof ResultData)) {
            obj = ServiceUtil.callbackSuccess(obj);
        }
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = "yyyy-MM-dd HH:mm:ss";
        }
        return JSON.toJSONStringWithDateFormat(obj, dateFormat, SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullNumberAsZero,
                SerializerFeature.WriteNullBooleanAsFalse,
                SerializerFeature.WriteMapNullValue
        );
    }

    /**
     * 成功通用返回方法
     *
     * @param obj 需要返回的数据对象
     * @return 格式化为JOSN 后的字符串
     */
    protected String callbackSuccess(Object obj) {
        return callbackWithDateFormat(obj, null);
    }

    /**
     * 失败通用返回方法
     *
     * @param message 操作失败的描述信息
     * @return 格式化为JOSN 后的字符串
     */
    protected String callbackFail(String message) {
        return callbackWithDateFormat(ServiceUtil.callbackFail(message), null);
    }

    /**
     * 统一返回方法
     *
     * @param resultDataEnum 返回数据状态的枚举
     * @param obj            需返回的数据对象
     * @return 格式化为JOSN 后的字符串
     */
    protected String callback(ResultDataEnum resultDataEnum, Object obj) {
        return callbackWithDateFormat(ServiceUtil.callback(resultDataEnum, obj), null);
    }

    /**
     * 统一返回方法
     *
     * @param resultDataEnum 返回数据状态的枚举
     * @return 格式化为JOSN 后的字符串
     */
    protected String callback(ResultDataEnum resultDataEnum) {
        return callbackWithDateFormat(ServiceUtil.callback(resultDataEnum), null);
    }

    /**
     * 数据检验不通过时调用
     * @param bindingResult 校验返回的绑定对象
     * @return 格式化为JOSN 后的字符串
     */
    public String callback(BindingResult bindingResult){
        List<FieldError> listError=bindingResult.getFieldErrors();
        for (FieldError error:listError) {
            //System.out.println(li.get(i).getField());//检验错误字段名
            return callbackFail(error.getDefaultMessage());
        }
        return callbackFail("別鬧");
    }

    /**
     * 获取分页对象(@RequestBody 接收的不要调用)
     */
    protected <T> Page<T> getPage() {
        return getPage(10);
    }
    /**
     * 获取分页对象(@RequestBody 接收的不要调用)
     */
    protected <T> Page<T> getPage(int size) {
        Page<T> page = new Page<>(HttpUtil.getInt(request, "pageNo", 1), HttpUtil.getInt(request, "pageSize", size));
        String sortOrder = request.getParameter("sortOrder");
        String sortField = request.getParameter("sortField");
        if(ObjectUtils.allNotNull(sortOrder,sortField)){
            //ascend 或者 descend
            if("ascend".equals(sortOrder)){
                page.setAsc(sortField);
            }else if("descend".equals(sortOrder)){
                page.setDesc(sortField);
            }
        }
        return page;
    }

    /**
     * 获取分页对象(统一通用)
     */
    protected <T> Page<T> getPage(long current,long size) {
        if(current==0){
            current=1;
        }
        if(size==0){
            size=10;
        }
        return new Page<>(current,size);
    }

    /**
     * 获取分页对象，并设置排序
     * @param pageNo
     * @param pageSize
     * @param <T>
     * @return
     */
    protected <T> Page<T> getPage(int pageNo,int pageSize) {
        Page<T> page = new Page<T>(HttpUtil.getInt(request, "pageNo", pageNo), HttpUtil.getInt(request, "pageSize", pageSize));
        String sortOrder = request.getParameter("sortOrder");
        String sortField = request.getParameter("sortField");
        if(ObjectUtils.allNotNull(sortOrder,sortField)){
            if("ascend".equals(sortOrder)){// acs 驼峰转下划线
                page.setAsc(camelToLine(sortField));
            }else if("descend".equals(sortOrder)){// desc 驼峰转下划线
                page.setDesc(camelToLine(sortField));
            }
        }
        return page;
    }

    private static Pattern humpPattern = Pattern.compile("[A-Z]");


    /**
     * 驼峰转下划线
     */
    private static String camelToLine(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }



}
